#include "StdAfx.h"
#include "Agent.h"
#include "Resource.h"
#include "TaxiAgent.h"
#include <algorithm>

CAgent::CAgent(int id, EAgentType type, CNode* node)
{        
    m_id = id;
    m_node = node;
    m_next = NULL;
    m_type = type;
    m_status = ESTATUS_STOPPED;
    m_steps = 0;
    m_pt = node->m_pt;
}

CAgent::~CAgent()
{
}

bool CAgent::Step(CEnv* env, int ms)
{
    if (m_next)
    {
        if (m_next == m_node->m_north)
            m_node->m_trafN++;
        if (m_next == m_node->m_east)
            m_node->m_trafE++;
        if (m_next == m_node->m_south)
            m_node->m_trafS++;
        if (m_next == m_node->m_west)
            m_node->m_trafW++;
    }

    m_steps++;
    return true;
}

EAgentType CAgent::GetType()
{
    return m_type;
}

EAgentStatus CAgent::GetStatus()
{
    return m_status;
}

int CAgent::GetId()
{
    return m_id;
}

int CAgent::GetStepCount()
{
    return m_steps;
}

void CAgent::Paint(CPaintDC& dc)
{
    // Select correct bitmap resource ID
    int id;
    if (m_type == ETYPE_CAR)
    {
        id = IDB_CAR;
    }
    else if (m_type == ETYPE_TAXI)
    {
        id = IDB_TAXI;

        CNodePtrVec* path = ((CCarAgent*)this)->GetPathVector();
        if (path)
        {
            CNodePtrVecIter it = std::find(path->begin(), path->end(), m_node);
            CPoint prev = m_pt;
            for (it++;  it != path->end(); it++)
            {
                DrawPathLine(prev, (*it)->m_pt, dc);
                prev = (*it)->m_pt;
            }

            DrawPathDest(path->back()->m_pt, dc);
        }
    }
    else
    {
        ASSERT(FALSE);
        TRACE("Unknown agent type encountered.\n");
    }

    // Prepare paint context
    CDC* mdc = new CDC;
    mdc->CreateCompatibleDC(&dc);

    // Load and select bitmap
    CBitmap bmp;
    bmp.LoadBitmap(id);
    mdc->SelectObject(&bmp);
    
    dc.BitBlt(m_pt.x - 4, m_pt.y - 4, 8, 8, mdc, 0, 0, SRCCOPY);
    delete mdc;
}

COLORREF CAgent::GetFill()
{
    switch (m_type)
    {
        case ETYPE_CAR: return ECOLOR_CAR_FILL;
        case ETYPE_TAXI: return ECOLOR_TAXI_FILL;
        default:
            TRACE("Uknown or null entity type encountered\n");
            ASSERT(false);
    }

    return 0;
}

COLORREF CAgent::GetStroke()
{
    switch (m_type)
    {
        case ETYPE_CAR: return ECOLOR_CAR_STROKE;
        case ETYPE_TAXI: return ECOLOR_TAXI_STROKE;
        default:
            TRACE("Uknown or null entity type encountered\n");
            ASSERT(false);
    }

    return 0;
}

CString CAgent::GetTypeString()
{
    switch (m_type)
    {
        case ETYPE_CAR: return CString("Car");
        case ETYPE_TAXI: return CString("Taxi");
        default: 
            TRACE("Unknown agent type encountered\n");
            ASSERT(FALSE);
            return ("Unknown"); 
    }

    return 0;
}

CString CAgent::GetStatusString()
{
    switch (m_status)
    {
        case ESTATUS_NULL: return CString("Doing nothing");
        case ESTATUS_STOPPED: return CString("Stopped");
        case ESTATUS_TRANSIT: return CString("In transit");
        default:
            TRACE("Unknown agent status encountered\n");
            ASSERT(FALSE);
            return CString("Unknown");
    }
}

void CAgent::DrawPathLine(CPoint& n1, CPoint& n2, CPaintDC& dc)
{
    CPen pen(PS_SOLID, 2, m_color);
    CPen* pOldPen = dc.SelectObject(&pen);
    dc.MoveTo(n1);
    dc.LineTo(n2);
    dc.StrokePath();
    dc.SelectObject(pOldPen);
}

void CAgent::DrawPathDest(CPoint& pt, CPaintDC& dc)
{
    CPen pen(PS_SOLID, 1, m_color);
    CBrush brush(m_color);
    CPen* pOldPen = dc.SelectObject(&pen);
    CBrush* pOldBrush = dc.SelectObject(&brush);

    dc.MoveTo(pt);
    dc.BeginPath();
    dc.AngleArc(pt.x, pt.y, 3, 0, 360);
    dc.EndPath();
    dc.StrokeAndFillPath();

    dc.SelectObject(pOldPen);
    dc.SelectObject(pOldBrush);
}